#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QScreen>
#include <QDebug>
#include <QToolTip>
#include <QPixmap>
#include <QList>
#include <vector>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    set_canva_size(this->width(),this->height());
     gaussianDialog= new GaussianDialog();
    connect(ui->Choose,SIGNAL(triggered()),this,SLOT(on_Choose_clicked()));
    //connect(ui->Gaosi,SIGNAL(triggered()),this,SLOT(on_Gaosi_clicked()));
    //高斯平滑
    connect(ui->actionGaussian_smoothing,SIGNAL(triggered()),this,SLOT(gaussian_smoothing()));
    connect(gaussianDialog,SIGNAL(acceptEvent(double)),this,SLOT(gaussian_dialog_accepted(double)));
}


void MainWindow::set_canva_size(int width, int height)
{
    ui->centralWidget->setMinimumWidth(width+35);
    ui->centralWidget->setMinimumHeight(height+25);
    ui->centralWidget->setMaximumWidth(width+35);
    ui->centralWidget->setMaximumHeight(height+25);
}


void MainWindow::on_Choose_clicked()
{
    QString OpenFile, OpenFilePath;
        QImage image;
        //打开文件夹中的图片文件
        OpenFile = QFileDialog::getOpenFileName(this,
                                                  "Please choose an image file",
                                                  "",
                                                  "Image Files(*.jpg *.png *.bmp *.pgm *.pbm);;All(*.*)");
        if( OpenFile != "" )
        {
            if( image.load(OpenFile) )
            {
                ui->imgLabel->setPixmap(QPixmap::fromImage(image));
            }
        }
        set_canva_size(image.width(),image.height());

}

void MainWindow::gaussian_smoothing()
{
    gaussianDialog->clearAll();
    gaussianDialog->setWindowTitle(tr("设置sigma值"));
    gaussianDialog->show();
}


void MainWindow::gaussian_dialog_accepted(double sigma)
{
    qDebug() << "gaussian_smoothing is triggered";

    //原图的图片信息
    QPixmap  pix = QPixmap(*ui->imgLabel->pixmap());
    QImage img  = pix.toImage();
    double imgWidth = ui->imgLabel->pixmap()->width();
    double imgHeight = ui->imgLabel->pixmap()->height();
    QPixmap newPix = QPixmap(imgWidth,imgHeight);
    QImage newImg = newPix.toImage();

    std::vector<int> tempRed;
    std::vector<int> tempGreen;
    std::vector<int> tempBlue;

    int size = 3;
    double dGaussianTemplate[3][11];
    generate_gaussian_template(dGaussianTemplate,size,sigma);
    int *gaussianTemplate = new int[size*size];
    int templateSum = 0;
    for(int i=0;i<size;i++)
    {
        for(int j=0;j<size;j++)
        {
            gaussianTemplate[i+j*size] = floor(dGaussianTemplate[i][j]);
            templateSum += floor(dGaussianTemplate[i][j]);
        }
    }

    int newRed = 0;
    int newGreen = 0;
    int newBlue = 0;
    int i,j,m,n,k;
    for(i=0; i<imgWidth;i++)
        for(j=0;j<imgHeight;j++)
        {
            if(i!=0 && j!= 0 && (i != imgWidth-1) && (j!=imgHeight-1))
            {
                // 处理红色通道
                for(m=i-1;m<i+2;m++)
                     for(n=j-1;n<j+2;n++)
                        tempRed.push_back(img.pixelColor(m,n).red());

                newRed = 0;
                for(k =0;k<9;k++)
                {
                    newRed += tempRed[k] * gaussianTemplate[k];
                }
                newRed =  newRed / templateSum;

                // 处理绿色通道
                for(m=i-1;m<i+2;m++)
                     for(n=j-1;n<j+2;n++)
                        tempGreen.push_back(img.pixelColor(m,n).green());

                newGreen = 0;
                for(int k=0;k<9;k++)
                {
                    newGreen += tempGreen[k] * gaussianTemplate[k];
                }
                newGreen =  newGreen / templateSum;

                // 处理蓝色通道
                for(m=i-1;m<i+2;m++)
                     for(n=j-1;n<j+2;n++)
                        tempBlue.push_back(img.pixelColor(m,n).blue());

                newBlue = 0;
                for(k =0;k<9;k++)
                {
                    newBlue += tempBlue[k] * gaussianTemplate[k];
                }
                newBlue =  newBlue/ templateSum;

                newImg.setPixelColor(i,j,QColor(newRed,newGreen,newBlue));
                tempRed.clear();
                tempGreen.clear();
                tempBlue.clear();
            }else
            {
               //处理边缘
                newImg.setPixelColor(i,j,img.pixelColor(i,j));
            }
        }

    //重新布局界面大小，并显示处理后的图像
    set_canva_size(newImg.width(),newImg.height());
    ui->imgLabel->setPixmap(QPixmap::fromImage(newImg));

    QString msg = tr("已完成高斯平滑处理");
    QMessageBox::information(this,tr("完成"),msg);
}


//输入一个数组作为模板的容器；确定模板的大小和sigma值，将结果返回给模板。
void generate_gaussian_template(double gTemp[][11], int kSize, double sigma)
{
    //static const double PI = 3.1415926535;
    //模板的中心位置
    int center = kSize / 2;
    double x2, y2;
    for(int i = 0; i<kSize; i++)
    {
        x2 = pow(i-center,2);
        for(int j =0; j<kSize;j++)
        {
            y2 = pow(j-center,2);
            double g = exp(-(x2+y2) / (2*sigma*sigma));
            g /= 2* 3.1415926535 * sigma;
            gTemp[i][j] = g;
        }
    }

    //将右上角系数进行归一化处理
    double t = 1 /gTemp[0][0];
    for(int i =0;i<kSize;i++)
        for(int j=0; j<kSize;j++)
            gTemp[i][j] *=t;
}



MainWindow::~MainWindow()
{
    delete ui;
}
